package com.woniuxy.school.dietary.order.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.json.JSONUtil;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.woniuxy.commons.core.exception.SchoolException;
import com.woniuxy.commons.core.model.Result;
import com.woniuxy.school.dietary.Dto.*;
import com.woniuxy.school.dietary.food.client.FoodClient;
import com.woniuxy.school.dietary.food.model.dto.FoodDto;
import com.woniuxy.school.dietary.food.model.from.FindFoodFrom;
import com.woniuxy.school.dietary.food.model.from.UpdateFoodFrom;
import com.woniuxy.school.dietary.from.*;
import com.woniuxy.school.dietary.order.entity.DietOrder;
import com.woniuxy.school.dietary.order.entity.DietOrderFood;
import com.woniuxy.school.dietary.order.entity.DietOrderLog;
import com.woniuxy.school.dietary.order.mapper.DietOrderFoodMapper;
import com.woniuxy.school.dietary.order.mapper.DietOrderLogMapper;
import com.woniuxy.school.dietary.order.mapper.DietOrderMapper;
import com.woniuxy.school.dietary.order.service.DietOrderService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.woniuxy.school.dietary.store.client.StoreClient;
import com.woniuxy.school.dietary.store.model.dto.FindStoreByIdDto;
import com.woniuxy.school.dietary.store.model.dto.FindStoreDto;
import com.woniuxy.school.dietary.store.model.from.FindDietTimeFrom;
import com.woniuxy.school.dietary.store.model.from.FindStoreFrom;


import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.redisson.api.RedissonClient;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 吴彦祖
 * @since 2025年05月14日
 */
@Service
@Slf4j
public class DietOrderServiceImpl extends ServiceImpl<DietOrderMapper, DietOrder> implements DietOrderService {
    @Autowired
    private FoodClient foodClient;
    @Resource
    private StoreClient storeClient;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Resource
    private DietOrderFoodMapper dietOrderFoodMapper;
    @Resource
    private DietOrderLogMapper dietOrderLogMapper;
    @Resource
    private DietOrderMapper dietOrderMapper;
    @Resource
    private RedissonClient redissonClient;
    @Resource
    private RabbitTemplate rabbitTemplate;
    @Resource
    private AlipayClient alipayClient;


    /**
     * 添加购物车实现类
     * @param
     */
    @Override
    public void addShopping(AddShoppingFrom from,Long userId) {
        //用于存放购物车中菜品id的key
        String cartKey = "shopping:userId:" + userId + ":store:" + from.getStoreId()+ ":items";
        //用于存放购物车中菜品详情的key
        String itemKey = "shopping:userId:" + userId + ":item:" + from.getStoreId() + ":" + from.getFoodId();
        String storeKey = "shopping:userId:" + userId + ":storeId:";
        //判断商家的合理性
        FindStoreFrom storeFrom = new FindStoreFrom();
         storeFrom.setStoreId(from.getStoreId());
        Result<FindStoreDto> store = storeClient.findStore(storeFrom);
        if (store.getCode()!=200) throw new SchoolException(store.getCode(),store.getMessage());
        if (store.getData()==null) throw new SchoolException(404,"商家信息有误");
        if (store.getData().getStatus()!=1) throw new SchoolException(500,"商家已禁用");
        if (store.getData().getStoreStatus()!=1) throw new SchoolException(500,"商家正在歇业中");
        FindStoreDto data1 = store.getData();//商家信息
        //判断选取的菜品合理性
        FindFoodFrom foodFrom = new FindFoodFrom();
        foodFrom.setFoodId(from.getFoodId());
        foodFrom.setStoreId(from.getStoreId());
        Result<FoodDto> foodDto = foodClient.findFood(foodFrom);
        if(foodDto.getCode()!=200) throw new SchoolException(foodDto.getCode(),foodDto.getMessage());
        if (foodDto.getData()==null) throw new SchoolException(404,"菜品信息有误");
        if (foodDto.getData().getState()!=1) throw new SchoolException(500,"菜品已下架");
        FoodDto food = foodDto.getData();
        //使用redis的zSet保存某个用户的购物车信息 key是用户id value是添加进购物车的商家id 时间戳为排序值
        //使用redis的hash保存一个商家的所有添加进购物车的菜品id
        //使用redis的hash保存一个菜品信息的菜品详情 key是商家id value是菜品id
        //先判断redis的hash判断添加进来的商品是否存在购物车中
        Boolean bool = redisTemplate.opsForHash().hasKey(cartKey, from.getFoodId()+"");
        if(bool!=null&&bool){
         //判断新增以后的数量会不会大于商品库存
            Integer count =Integer.parseInt(redisTemplate.opsForHash().get("shopping:userId:" + userId + ":item:" + from.getStoreId() + ":" +  from.getFoodId()+"", "count").toString());
            if (count+from.getCount()>food.getCount()) throw new SchoolException(500,"库存不足");
            //数据合理的情况下增加购物车数量即可
            redisTemplate.opsForHash().increment(itemKey, "count", from.getCount());
        }else{
            //不存在新增菜品id进hash
            redisTemplate.opsForHash().put(cartKey, from.getFoodId()+"", from.getCount()+"");
            //新增该商品的购物车信息进hash
            HashMap<String, String> map = new HashMap<>();
            map.put("foodId", from.getFoodId()+"");
            map.put("count", from.getCount()+"");
            map.put("coverPhoto", food.getCoverPhoto());
            map.put("price", food.getPrice());
            map.put("foodName", food.getFoodName());
            map.put("storeId", from.getStoreId()+"");
            map.put("storeName", data1.getStoreName());
            map.put("storePhone", data1.getPhone());
            map.put("storeAddress", data1.getAddress());
            redisTemplate.opsForHash().putAll(itemKey , map);
            //新增商家中菜品记录
            redisTemplate.opsForZSet().add(storeKey,from.getStoreId()+"",new Date().getTime());
        }
    }
//
    @Override
    public void deleteShopping(DeleteShoppingFrom from, Long userId) {
        //用于存放购物车中菜品id的key
        String cartKey = "shopping:userId:" + userId + ":store:" + from.getStoreId()+ ":items";
        //用于存放购物车中菜品详情的key
        String itemKey = "shopping:userId:" + userId + ":item:" + from.getStoreId() + ":" + from.getFoodId();
        String storeKey = "shopping:userId:" + userId + ":storeId:";

// 校验菜品是否存在
        FindFoodFrom foodFrom = new FindFoodFrom();
        foodFrom.setFoodId(from.getFoodId());
        foodFrom.setStoreId(from.getStoreId());
        Result<FoodDto> food = foodClient.findFood(foodFrom);
        if (food.getCode() != 200 || food.getData() == null) {
            throw new SchoolException(404, "菜品信息有误");
        }

// 检查该菜品是否存在于购物车中
        Boolean exists = redisTemplate.opsForHash().hasKey(cartKey,from.getFoodId()+"");
        if (exists == null || !exists) {
            throw new SchoolException(404, "该商品没有添加进购物车");
        }

// 删除菜品项和哈希表中的记录
        redisTemplate.opsForHash().delete(cartKey, from.getFoodId() + "");
        redisTemplate.delete(itemKey);

// 删除 ZSet 中对应的 storeId（如果有）
        String storeId = String.valueOf(from.getStoreId());
        redisTemplate.opsForZSet().remove(storeKey, storeId);

// 如果 ZSet 现在为空，则删除整个 key
        Long zsetSize = redisTemplate.opsForZSet().size(storeKey);
        if (zsetSize == null || zsetSize == 0) {
            redisTemplate.delete(storeKey);
        }


    }
//
    @Override
    public findShoppingDto findShopping(FindShoppingFrom from, Long userId) {
        // 构造 storeId 的 ZSet key
        String storeKey = "shopping:userId:" + userId + ":storeId:";

        // 默认分页参数
        if (from.getPageNum() == null || from.getPageNum() < 1) from.setPageNum(1L);
        if (from.getPageSize() == null || from.getPageSize() < 1) from.setPageSize(10L);

        // 获取当前用户购物车中的商家数量
        Long total = redisTemplate.opsForZSet().size(storeKey);
        if (total == null || total <= 0) {
            throw new SchoolException(404, "购物车为空");
        }

        // 计算总页数
        long pageNum = from.getPageNum();
        long pageSize = from.getPageSize();
        long pages = (total + pageSize - 1) / pageSize;

        // 计算起始索引
        long start = (pageNum - 1) * pageSize;
        long end = start + pageSize - 1;

        // 获取当前页的商家 ID 列表
        Set<String> storeIds = redisTemplate.opsForZSet().reverseRange(storeKey, start, end);
        if (storeIds == null || storeIds.isEmpty()) {
            throw new SchoolException(404, "当前页无商家数据");
        }

        // 创建返回 DTO
        findShoppingDto shoppingDto = new findShoppingDto();
        List<Stores> storesList = new ArrayList<>();

        for (String storeId : storeIds) {
            Stores stores = new Stores();
           // 构造该商家下的菜品 hash key
            String cartKey = "shopping:userId:" + userId + ":store:" + storeId + ":items";
            Set<Object> foodIdSet = redisTemplate.opsForHash().keys(cartKey);

            List<ShoppingDto> foodList = new ArrayList<>();
            if (foodIdSet != null && !foodIdSet.isEmpty()) {
                for (Object foodIdObj : foodIdSet) {
                    String foodId = foodIdObj.toString();
                    String itemKey = "shopping:userId:" + userId + ":item:" + storeId + ":" + foodId;

                    Map<Object, Object> map = redisTemplate.opsForHash().entries(itemKey);
                    if (map != null && !map.isEmpty()) {
                        ShoppingDto dto = new ShoppingDto();
                        dto.setStoreName(map.get("storeName") == null ? "" : map.get("storeName").toString());
                        dto.setStorePhone(map.get("storePhone") == null ? "" : map.get("storePhone").toString());
                        dto.setStoreId(map.get("storeId") == null ? "" : map.get("storeId").toString());
                        dto.setFoodId(Long.valueOf(map.get("foodId") == null ? "0" : map.get("foodId").toString()));
                        dto.setFoodName(map.get("foodName") == null ? "" : map.get("foodName").toString());
                        dto.setCoverPhoto(map.get("coverPhoto") == null ? "" : map.get("coverPhoto").toString());
                        dto.setPrice(map.get("price") == null ? "0" : map.get("price").toString());

                        foodList.add(dto);
                    }
                }
            }
            stores.setList(foodList);
            storesList.add(stores);
        }
        // 设置分页信息
        shoppingDto.setStores(storesList);
        shoppingDto.setTotal(total);
        shoppingDto.setPages(pages);
        shoppingDto.setPageNum(pageNum);
        shoppingDto.setPageSize(pageSize);
        return shoppingDto;


    }
//
    @Override
    public void updateShopping(UpdateShoppingFrom from, Long userId) {
        //用于存放购物车中菜品id的key
        String cartKey = "shopping:userId:" + userId + ":store:" + from.getStoreId()+ ":items";
        //用于存放购物车中菜品详情的key
        String itemKey = "shopping:userId:" + userId + ":item:" + from.getStoreId() + ":" + from.getFoodId();
       //存放商家id
        String storeKey = "shopping:userId:" + userId + ":storeId:";
        //前置判断 判断菜品的合理性
        FindFoodFrom foodFrom = new FindFoodFrom();
        foodFrom.setFoodId(from.getFoodId());
        foodFrom.setStoreId(from.getStoreId());
        Result<FoodDto> food = foodClient.findFood(foodFrom);
        if (food.getCode()!=200) throw new SchoolException(food.getCode(),food.getMessage());
        if (food.getData()==null) throw new SchoolException(404,"菜品信息有误");
        //判断该菜品是否在购物车中
        Object o = redisTemplate.opsForHash().get(cartKey, from.getFoodId() + "");
        if(o==null){
            throw new SchoolException(404,"该商品没有添加进购物车");
        }else{
            //判断此时修改的数量的合理性
            //如果商品数量小于0了就直接删除该商品信息
            if(from.getCount()<0){
                // 删除菜品项和哈希表中的记录
                redisTemplate.opsForHash().delete(cartKey, from.getFoodId() + "");
                redisTemplate.delete(itemKey);

// 删除 ZSet 中对应的 storeId（如果有）
                String storeId = String.valueOf(from.getStoreId());
                redisTemplate.opsForZSet().remove(storeKey, storeId);

// 如果 ZSet 现在为空，则删除整个 key
                Long zsetSize = redisTemplate.opsForZSet().size(storeKey);
                if (zsetSize == null || zsetSize == 0) {
                    redisTemplate.delete(storeKey);
                }

            }else{
                //判断修改的数量是否合理
                if(from.getCount()>food.getData().getCount()){
                    throw new SchoolException(404,"库存不足");
                }
                //直接修改购物车详情
                redisTemplate.opsForHash().put(itemKey,"count",from.getCount()+"");
            }
        }

    }

    @Override
    public void clearShopping(Long userId) {
        //用于存放购物车中菜品id的key
//        String cartKey = "shopping:userId:" + userId + ":store:" + from.getStoreId()+ ":items";
        //用于存放购物车中菜品详情的key
//        String itemKey = "shopping:userId:" + userId + ":item:" + from.getStoreId() + ":" + from.getFoodId();
        //存放商家id
        String storeKey = "shopping:userId:" + userId + ":storeId:";
        //判断用户是否存在购物车
        Long size = redisTemplate.opsForZSet().size(storeKey);
        if (size==null){
            //不存在抛出异常
            throw new RuntimeException("该用户没有购物车");
        }else{
            //存在  先拿到所有商家id
            Set<String> range = redisTemplate.opsForZSet().range(storeKey, 0, -1);
            for (String storeId : range) {
                //拿到所有菜品id
                Map<Object, Object> map = redisTemplate.opsForHash().entries("shopping:userId:" + userId + ":store:" + Long.valueOf(storeId) + ":items");
               //就是每一个菜品id
                Set<Object> objects = map.keySet();
                //通过菜品id删除菜品详情
                for (Object obj : objects) {
                    redisTemplate.delete("shopping:userId:" + userId + ":item:" +Long.valueOf(storeId) + ":" + obj.toString());
                }
                //删除菜品id
                redisTemplate.delete("shopping:userId:" + userId + ":store:" + Long.valueOf(storeId)+ ":items");

            }
            redisTemplate.delete(storeKey);
        }
    }
//
    @Override
    public OrderDto addOrder(AddOrderFrom from, Long userId) {
        //将foodid排序
        Arrays.sort(from.getFoodId());
        //创建返回类
        OrderDto dto = new OrderDto();
        List<OrderFoodInfo> list1 = new ArrayList<>();
        //用于存放购物车中菜品id的key
        String cartKey = "shopping:userId:" + userId + ":store:" + from.getStoreId()+ ":items";
        //用于存放购物车中菜品详情的key
//

        //存放商家id
        String storeKey = "shopping:userId:" + userId + ":storeId:";
        //判断商家的合理性
        FindStoreFrom storeFrom = new FindStoreFrom();
        storeFrom.setStoreId(from.getStoreId());
        Result<FindStoreDto> store = storeClient.findStore(storeFrom);
        if (store.getCode()!=200) throw new SchoolException(store.getCode(),store.getMessage());
        if (store.getData()==null) throw new SchoolException(501,"商家信息有误");
        if (store.getData().getStatus()!=1) throw new SchoolException(502,"商家已禁用");
        if (store.getData().getStoreStatus()!=1) throw new SchoolException(503,"商家正在歇业中");
        //商家在线时间判断
        FindDietTimeFrom timeFrom = new FindDietTimeFrom();
        timeFrom.setStoreId(from.getStoreId());
        timeFrom.setOrderTime(LocalDateTime.now());
        Boolean bool = storeClient.findDietTime(timeFrom).getData();
        if (!bool){
        throw new SchoolException(504,"商家不在营业时间");
         }
        //商家信息
        FindStoreDto data1 = store.getData();
        //判断菜品合理性
        //存放菜品信息  因为id排序 所有如果存在数据 购物车信息和菜品的详情一一对应
        HashMap<Long, FoodDto> food = new HashMap<>();
        for (Long aLong : from.getFoodId()) {
            //判断选取的菜品合理性
            FindFoodFrom foodFrom = new FindFoodFrom();
            foodFrom.setFoodId(aLong);
            foodFrom.setStoreId(from.getStoreId());
            Result<FoodDto> foodDto = foodClient.findFood(foodFrom);
            if(foodDto.getCode()!=200) throw new SchoolException(foodDto.getCode(),foodDto.getMessage());
            if (foodDto.getData()==null) throw new SchoolException(404,"菜品信息有误");
            if (foodDto.getData().getState()!=1) throw new SchoolException(500,"菜品已下架");
            food.put(aLong, foodDto.getData());
        }
        Long[] foodId = from.getFoodId();
        Integer num=0;//菜品数量
        String foodName="";//菜品名称
        String storeName="";//店铺名称
        String storePhone="";//店铺电话
        BigDecimal total = new BigDecimal(0);
        //使用单例模式获取雪花算法对象
            String orderNum = getSnowflake().nextIdStr();
       //根据传入id 查询redis中的购物车信息
        //如果出现没查到的情况 抛出异常
        //创建一个list集合保存所有菜品的信息
        ArrayList<Map<Object, Object>> list = new ArrayList<>();
        for (Long id : foodId) {
            //判断是否存在购物车信息
            Boolean key = redisTemplate.opsForHash().hasKey(cartKey, id + "");
            if (key==null&&!key){
                throw new SchoolException(507,"该商品没有添加进购物车");
            }
            //存在菜品就获取菜品详情放进list中
            Map<Object, Object> map1 = redisTemplate.opsForHash().entries("shopping:userId:" + userId + ":item:" + from.getStoreId() + ":" + id);
            list.add(map1);
        }
//        //上锁  先判断缓存中数量的合理性 合理就要修改菜品的状态
        RLock[] lock =new RLock[foodId.length];
        for (int i = 0; i < foodId.length; i++) {
            //给每一个菜品上锁
            RLock rLock = redissonClient.getFairLock("lock:foodId:" + foodId[i]);
            lock[i] = rLock;
        }
        RLock rLock = redissonClient.getMultiLock(lock);
        try {
            rLock.lock();
            //遍历购物车信息
            for (Map<Object, Object> map : list) {
                //拿到商户名称
                storeName=map.get("storeName").toString();
//            拿到商铺电话
                storePhone=map.get("storePhone").toString();
                //拿到购物车中菜品的数量
                Integer count = Integer.parseInt(map.get("count").toString());
                //拿到菜品信息
                FoodDto foodDto = food.get(Long.valueOf(map.get("foodId").toString()));
                //判断库存量的合理性
                if (count>foodDto.getCount()) throw new SchoolException(506,"该商品库存不足");
                //多个菜品的情况下累加菜品数量·
                num+=count;
                //计算总价
                total = total.add(new BigDecimal(map.get("price").toString()).multiply(new BigDecimal(map.get("count").toString())));
                //生成菜品详情返回类
                OrderFoodInfo orderFoodInfo = new OrderFoodInfo();
                orderFoodInfo.setFoodName(foodDto.getFoodName());
                orderFoodInfo.setCount(num);
                orderFoodInfo.setPrice(foodDto.getPrice());
                orderFoodInfo.setStoreName(storeName);
                orderFoodInfo.setStorePhone(storePhone);
                list1.add(orderFoodInfo);
                dto.setOrderNum(orderNum);
                //生成订单菜品关联信息
                DietOrderFood dietOrderFood = new DietOrderFood();
//                //设置订单编号
                dietOrderFood.setOrderNum(orderNum);
//              //设置菜品id
                dietOrderFood.setFoodId(foodDto.getId());
////                //设置菜品名称
                dietOrderFood.setFoodName(foodDto.getFoodName());
////                //设置菜品数量
                dietOrderFood.setCount(count);
////                //设置菜品金额
                dietOrderFood.setPrice(foodDto.getPrice());
                dietOrderFoodMapper.insert(dietOrderFood);
//              //删除购物车信息
                redisTemplate.opsForHash().delete(cartKey,foodDto.getId()+"");
                redisTemplate.delete("shopping:userId:" + userId + ":item:" + from.getStoreId() + ":" +foodDto.getId()+"");
                //                //将订单编号放进队列中
                rabbitTemplate.convertAndSend("order-delay",orderNum);
                //                //将此时菜品的库存减去该菜品的count
//                //更新冻结库存数量
//                //修改此时菜品的数量 新增冻结量
                UpdateFoodFrom from1 = new UpdateFoodFrom();
                from1.setFoodId(foodDto.getId());
                from1.setFreeze(count+foodDto.getFreeze());
                from1.setCount(foodDto.getCount() - count);
                Result result = foodClient.updateFood(from1);
                if (result.getCode() != 200) throw new SchoolException(result.getCode(), result.getMessage());
            }
            dto.setPrice(total.toString());
            dto.setOrderFoodInfo(list1);
            // 删除 ZSet 中对应的 storeId（如果有）
            String storeId1 = String.valueOf(from.getStoreId());
            redisTemplate.opsForZSet().remove(storeKey, storeId1);
            // 如果 ZSet 现在为空，则删除整个 key
            Long zsetSize = redisTemplate.opsForZSet().size(storeKey);
            if (zsetSize == null || zsetSize == 0) {
                redisTemplate.delete(storeKey);
            }
            //生成订单
            DietOrder dietOrder = new DietOrder();
            dietOrder.setOrderNum(orderNum);
            dietOrder.setStoreId(from.getStoreId());
            dietOrder.setOrderUser(userId);
            dietOrder.setEvaluate(1);
            dietOrder.setPrice(total.toString());
            dietOrder.setOrderPhone(from.getOrderPhone());
            dietOrder.setReceiveName(from.getReceiveName());
            dietOrder.setAddress(from.getAddress());
            dietOrder.setOrderDate(LocalDateTime.now());
            dietOrder.setState(1);
            dietOrderMapper.insert(dietOrder);
            //            //打印日志信息
            log.info("用户下单成功,订单号："+orderNum, orderNum);
//            //生产订单日志
            DietOrderLog dietOrderLog = new DietOrderLog();
//            //设置订单编号
            dietOrderLog.setOrderNum(orderNum);
//            //设置状态为待付款
            dietOrderLog.setOrderState(1);
            dietOrderLog.setOperName("下单操作");
            dietOrderLog.setOperReason("饿了");
            dietOrderLog.setOperUser(userId);
            dietOrderLog.setOperDate(LocalDateTime.now());
            dietOrderLog.setOperContent("下单操作,进入待付款状态");
            dietOrderLogMapper.insert(dietOrderLog);
        }finally {
          rLock.unlock();
//
        }
        return dto;
    }
//
    @Override
    public void cancelOrder(String orderNum) {
       //判断传入订单是否存在
        QueryWrapper<DietOrder> wrapper = new QueryWrapper<>();
//        wrapper.eq("orderUser", userId);
        if (orderNum != null){
            wrapper.eq("orderNum", orderNum);
        }
        //前置判断 判断订单合理性
        //只能取消未付款的订单
        DietOrder dietOrder = dietOrderMapper.selectOne(wrapper);
        if (dietOrder == null) throw new SchoolException(404, "订单不存在");

        if (dietOrder.getState() != 1) throw new SchoolException(406, "该订单已支付");
        //取消订单的幂等性处理 防止重复操作
        if (dietOrder.getState()==5)throw  new SchoolException(407,"订单已取消");
        //取消操作
        dietOrder.setState(5);
        dietOrder.setCancelDate(LocalDateTime.now());
        dietOrderMapper.updateById(dietOrder);
        //删除冻结量 恢复库存
        QueryWrapper<DietOrderFood> orderFood = new QueryWrapper<>();
        orderFood.eq("orderNum", orderNum);
        List<DietOrderFood> foods = dietOrderFoodMapper.selectList(orderFood);


            if (foods != null&&!foods.isEmpty()) {
                for (DietOrderFood dietOrderFood : foods) {
                    //查询菜品信息  回滚库存
                    FindFoodFrom from = new FindFoodFrom();
                    from.setFoodId(dietOrderFood.getFoodId());
                    Result<FoodDto> food = foodClient.findFood(from);
                    UpdateFoodFrom from1 = new UpdateFoodFrom();
                    from1.setFoodId(dietOrderFood.getFoodId());
                    from1.setCount(food.getData().getCount() + dietOrderFood.getCount());
                    from1.setFreeze(food.getData().getFreeze() - dietOrderFood.getCount());
                    foodClient.updateFood(from1);
                }
            }
//        //生成订单取消日志
//        DietOrderLog dietOrderLog = new DietOrderLog();
//        dietOrderLog.setOrderNum(orderNum);
//        dietOrderLog.setOrderState(5);
//        dietOrderLog.setOperName("取消操作");
//        dietOrderLog.setOperReason("取消订单");
//        dietOrderLog.setOperUser(userId);
//        dietOrderLog.setOperDate(LocalDateTime.now());
//        dietOrderLog.setOperContent("取消操作,进入取消状态");
//        dietOrderLogMapper.insert(dietOrderLog);
//        log.info("订单取消成功，订单号: ", orderNum);

    }
//
    @Override
    public void updateOrder(UpdateOrderFrom from, Long userId) {
        //查询订单详情
        QueryWrapper<DietOrder> wrapper = new QueryWrapper<>();
        wrapper.eq("orderNum", from.getOrderNum());
        DietOrder dietOrder = dietOrderMapper.selectOne(wrapper);
        if (dietOrder == null) throw new SchoolException(404, "订单不存在");
        if (dietOrder.getOrderUser() != userId) throw new SchoolException(405, "该订单不属于当前用户");
        if (dietOrder.getState() != 1) throw new SchoolException(406, "该订单不处于待支付状态，不能修改");
        dietOrder.setAddress(from.getAddress());
        dietOrder.setOrderPhone(from.getPhone());
        dietOrder.setReceiveName(from.getReceiveName());
        dietOrderMapper.updateById(dietOrder);
        //打印日志
        log.info("订单更新成功，订单号:{}", from.getOrderNum());
    }
//
    @Override
    public PageInfoDto findMyOrder(FindMyOrderFrom from, Long userId) {
        //创建分页对象
        PageInfoDto pageInfoDto = new PageInfoDto();
        //查询我的订单
        QueryWrapper<DietOrder> wrapper = new QueryWrapper<>();
        wrapper.eq("orderUser", userId);
        //计算总记录数
        Long total = dietOrderMapper.selectCount(wrapper);
        pageInfoDto.setTotal(total);
//        //计算起始位置
        Long start = (from.getPageNum() - 1) * from.getPageSize();
//        //计算结束位置
        Long end = start + from.getPageSize();
        //计算总页数
        pageInfoDto.setPages(total % from.getPageSize() == 0 ? total / from.getPageSize() : total / from.getPageSize() + 1);
        pageInfoDto.setPageNum(from.getPageNum());
        pageInfoDto.setPageSize(from.getPageSize());
        //分页查询
         List<DietOrder> page=dietOrderMapper.selectByLimit(start,end,userId );
        pageInfoDto.setList(page);
        return pageInfoDto;
    }

    @Override
    public String pay(String orderNum,Long userId) throws AlipayApiException {
        // 打印日志
//        System.out.println(alipayClient);

// 查询订单
        QueryWrapper<DietOrder> wrapper = new QueryWrapper<>();
        wrapper.eq("orderNum", orderNum);
        DietOrder dietOrder = dietOrderMapper.selectOne(wrapper);

// 校验订单
        if (dietOrder == null) throw new SchoolException(1005, "订单不存在");
        if (dietOrder.getState() != 1) throw new SchoolException(1006, "该订单不处于待支付状态");
        if (dietOrder.getOrderUser() != userId) throw new SchoolException(1007, "该订单不属于当前用户");

// 构建支付参数
        Map<String, Object> map = new HashMap<>();
        map.put("out_trade_no", orderNum);
        map.put("total_amount", dietOrder.getPrice().toString()); // 注意转成字符串
        map.put("subject", "西南大学后台管理");
        map.put("body", "订单支付");
        map.put("product_code", "FAST_INSTANT_TRADE_PAY");

// 设置过期时间
        LocalDateTime orderDate = dietOrder.getOrderDate();
        LocalDateTime expireTime = orderDate.plusMinutes(15);
        String timeExpire = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(expireTime);
        map.put("time_expire", timeExpire);

// 转成 JSON 字符串
        String bizContent = JSONUtil.parseObj(map).toString();

// 创建请求对象
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
        request.setBizContent(bizContent);
        //支付成功的前端回调函数
        request.setReturnUrl("http://www.baidu.com");
       //支付成功的后端回调函数
        //在回调函数中修改订单状态信息
        request.setNotifyUrl("http://q2a828.natappfree.cc/order/dietOrder/notify");

// 发起支付
        AlipayTradePagePayResponse response = alipayClient.pageExecute(request);

        if (response.isSuccess()) {
            return response.getBody(); // 返回 HTML 表单
        } else {
            log.error("支付宝支付失败：{}", response.getSubMsg());
            throw new SchoolException(1008, "支付失败：" + response.getSubMsg());
        }


    }

    @Override
    public String callBack(String orderNum,String payment) throws AlipayApiException {

        DietOrder order = dietOrderMapper.selectOne(new QueryWrapper<DietOrder>().eq("orderNum", orderNum));
        if (order==null) throw new SchoolException(1005, "订单不存在");
        if (order.getState()!=1) throw new SchoolException(1006, "该订单不处于待支付状态");
        //修改此时的状态为已付款
        order.setState(2);
        //设置支付时间
        order.setRemarks(payment);
        //修改订单信息
        dietOrderMapper.update(order,new QueryWrapper<DietOrder>().eq("orderNum", orderNum));
        //从订单菜品关联表获取菜品id
        List<DietOrderFood> orderNum1 = dietOrderFoodMapper.selectList(new QueryWrapper<DietOrderFood>().eq("orderNum", orderNum));
        //上锁
        RLock lock = redissonClient.getFairLock(orderNum+ "");
        try {
        for (DietOrderFood food1 : orderNum1) {
            lock.lock();
            FindFoodFrom findFoodFrom = new FindFoodFrom();
            findFoodFrom.setFoodId(food1.getFoodId());
            Result<FoodDto> food = foodClient.findFood(findFoodFrom);
            //菜品信息
            FoodDto foodDto = food.getData();
            //支付成功修改菜品的冻结量
            UpdateFoodFrom updateFoodFrom = new UpdateFoodFrom();
            updateFoodFrom.setFoodId(food1.getFoodId());
            updateFoodFrom.setFreeze(foodDto.getFreeze()-food1.getCount());
            updateFoodFrom.setCount(foodDto.getCount());
            foodClient.updateFood(updateFoodFrom);
        }
        }finally {
            lock.unlock();
        }
        //生成支付成功日志
        DietOrderLog dietOrderLog = new DietOrderLog();
        dietOrderLog.setOrderNum(orderNum);
        dietOrderLog.setOrderState(2);
        dietOrderLog.setOperName("支付宝支付成功");
        dietOrderLog.setOperUser(order.getOrderUser());
        dietOrderLog.setOperContent("支付宝支付成功");
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        dietOrderLog.setOperDate(LocalDateTime.parse(payment,formatter));
        dietOrderLogMapper.insert(dietOrderLog);
        return "success";
    }
//
    @Override
    public PageInfoDto storeFindOrder(StoreFindOrderFrom from, Long storeId) {
        //创建同意返回类
        PageInfoDto dto = new PageInfoDto();
        QueryWrapper<DietOrder> wrapper = new QueryWrapper<DietOrder>().eq("storeId", storeId);
        //得到该商家的订单数量
        Long aLong = dietOrderMapper.selectCount(wrapper);
        if (aLong!=0) throw new SchoolException(1008,"该商家没有订单");
        //设置总数
        dto.setTotal(aLong);
        //计算起始下标
        Long start = (from.getPageNum()-1)*from.getPageSize();
        //计算结束下标
        Long end=start +  from.getPageSize();
        dto.setPageNum(from.getPageNum());
        dto.setPageSize(from.getPageSize());
        //计算总页数
        long pages= aLong%from.getPageSize()==0?aLong/from.getPageSize():aLong/from.getPageSize()+1;
        List<DietOrder> list=dietOrderMapper.storeFindOrder(start,end,storeId);
        dto.setList(list);
        return dto;
    }

    @Override
    public DietOrder findOrderByOrderNum(String orderNum) {
        return dietOrderMapper.selectOne(new QueryWrapper<DietOrder>().eq("orderNum", orderNum));
    }

    //
//
    public static Snowflake getSnowflake(){
        Snowflake snowflake=null ;
        if (snowflake == null){
            snowflake=new Snowflake(1,1);
        }
        return snowflake;
    }


}
